#!/bin/sh
#Barry Kauler 2007 www.puppylinux.com
#2007 Lesser GPL licence v2 (http://www.fsf.org/licensing/licenses/lgpl.html)
#created for v3.01, oct 2007.
#w482 use xorriso instead of cdrtools/cdrkit if installed,
#w482 variables CDRECORD and MKISOFS are exportedby rc.shutdown and savesessio-dvd.
#w482 replace -pad in cdrecord with padsize=300k.
#100820 relocate /var/local so it will get saved.
#100913 simplified puppy filenames.
#100916 no longer have DISTRO_DEVXSFS in /etc/DISTRO_SPECS.(it was only there briefly)
#120823 rerwin: multisession: screen out /.XLOADED when save.

KERNELVER="`uname -r`" #w478

DEVCONSOLE="/dev/tty" #running in rxvt.
pidof X >/dev/null || pidof Xorg  >/dev/null || DEVCONSOLE="/dev/console" #when X not running

#waittrayclosedfunc is used by /etc/rc.d/rc.shutdown and /usr/sbin/savesession-dvd.
#v2.16...
waittrayclosed_func() {
 CDDRV="$1"
 if [ "`cddetect -d${CDDRV} | grep '^tray open!'`" != "" ];then #v2.22
  echo -e "\\033[1;31mThe media tray appears to be open." >$DEVCONSOLE #31=red
  echo -en "Please close tray then press ENTER key:\\033[0;39m " >$DEVCONSOLE
  read waitaenter
 fi
 echo -e "\\033[1;34mIF STOPPED LONG TIME AT THIS MSG, MAKE SURE TRAY IS CLOSED THEN PRESS ENTER KEY:\\033[0;39m " >$DEVCONSOLE #34=blue
}

#multisavefunc is used by /etc/rc.d/rc.shutdown and /usr/sbin/savesession-dvd.
#these variables must be preset before calling...
#PUPSAVE=partition,filesystem,/${DISTRO_FILE_PREFIX}save.2fs where 1st 2 are the partition holding the file.
#SAVEPART=filesystem which is same as above filesystem.
multisavefunc() {
 #save session to folder on multisession CD/DVD.
 [ "$CDRECORD" = "" ] && CDRECORD='cdrecord' #w482 precaution.
 [ "$MKISOFS" = "" ] && MKISOFS='mkisofs' #w482 precaution.
 export MKISOFS
 touch -c /.badfolders #update modifytime, so will get saved. badlist, see init script.
 MSPATTERN="/dev/$SAVEPART " #v2.22
 if [ "`mount | grep "$MSPATTERN"`" != "" ];then
  echo "/dev/$SAVEPART mounted, must unmount it..."
  fuser -k -m /dev/$SAVEPART
  sync
  umount /dev/$SAVEPART 2> /dev/null
 fi
 CDR="/dev/$SAVEPART"

 if [ "`mount | grep "$CDR"`" != "" ];then #v3.01
  dialog --msgbox "The drive $CDR could not be unmounted,
so current session cannot be saved to it.
This can happen if PC has insufficient RAM to
copy all files off the CD, or an application
is using the CD and cannot be killed.

Press ENTER key..." 0 0 >$DEVCONSOLE
  clear >$DEVCONSOLE
  return
 fi
  
 ##v3.01 have restored this... 
 HDRCDR="$CDR" #w482
 dialog --yes-label "SAVE" --no-label "NO SAVE" --yesno "Please insert the Puppy live-CD/DVD media that you booted from, into the same CD/DVD drive that you booted from -- this is /dev/$SAVEPART and it must be a burner drive!

Insert CD/DVD media now, then press ENTER key to save session...
Or, press TAB then ENTER to not save session..." 0 0 >$DEVCONSOLE
 if [ ! $? -eq 0 ];then
  eject $CDR
  dialog --msgbox "Have not saved session to live-CD/DVD.
Remove CD/DVD media if you wish.
Do not press close button on drive.
Press ENTER key to close drive tray" 0 0 >$DEVCONSOLE
  eject -t $CDR
  sleep 1
  clear >$DEVCONSOLE
  waittrayclosed_func $CDR #v2.16
  return
 fi

 clear >$DEVCONSOLE
 if [ "`cddetect -d${CDR} | grep '^no disc!'`" != "" ];then #v2.22
  echo -e "\\033[1;31mIt seems that the media is not inserted." >$DEVCONSOLE #31=red
  echo -en "Please insert media then press ENTER key:\\033[0;39m " >$DEVCONSOLE
  read waitaenter
 fi
 
 MEDIATYPE="CD"
 waittrayclosed_func $CDR #v2.16
 DVDRWMEDIAINFO="`dvd+rw-mediainfo $CDR 2>&1`"
 [ "`echo -n "$DVDRWMEDIAINFO" | grep --extended-regexp "non\\-DVD|not a DVD unit|Input/Output error|Input/output error|Invalid argument"`" = "" ] && MEDIATYPE="DVD"

 #if new version iso inserted, need to save all files, not just changed/new...
 MSPATTERN="$CDR "
 DVDMNTPT="`mount | grep "$MSPATTERN" | tr -s " " | cut -f 3 -d " "`" #in case not unmounted.
 if [ "$DVDMNTPT" = "" ];then
  mkdir -p /tmp/dvdmntpt
  mount -t iso9660 $CDR /tmp/dvdmntpt
  [ $? -eq 0 ] && DVDMNTPT="/tmp/dvdmntpt"
 fi
 if [ "$DVDMNTPT" != "" ];then
  if [ $ORIGPUPMODE -eq 77 ];then #bypass first boot, PUPMODE=5. v2.22
   [ "`find $DVDMNTPT -maxdepth 1 -type d -name '20[0-9][0-9]*'`" != "" ] && NEWISO="yes"
  fi
  umount $CDR 2>/dev/null
 fi

 pup_rw="/initrd/pup_rw"
 [ -L /initrd/pup_rw ] && pup_rw="$(readlink /initrd/pup_rw)" #new init

 pup_ro1='/initrd/pup_ro1'
 [ -L /initrd/pup_ro1 ] && pup_ro1="$(readlink /initrd/pup_ro1)" #new init

 #want to copy contents of ${pup_rw} to a new folder on /dev/$SAVEPART...
 MYDATE="`date "+%Y-%m-%d-%H-%M"`" #this will become the folder name on cd.

 SAVEABORT="" #v3.01
 while [ 1 ] #WHILELOOP1
 do
  #if have new live-cd, need a 'full save', not just what is in pup_rw. Maybe easiest
  #way is to save two tracks, pup_ro1, which has all prior saved folders read from cd
  #at bootup, then save latest session, pup_rw...
  if [ "$NEWISO" = "yes" ];then
   echo "Burning data from previous $MEDIATYPE to first track..." >$DEVCONSOLE
   #use last folder name from previous cd, to avoid name conflict with next folder...
   FOLDEROLD="`echo -n "$PUPSAVE" | cut -f 3 -d ','`"
   #minimal error checking here, errors reported when save current session (below)...
   if [ "$MEDIATYPE" = "CD" ];then
    waittrayclosed_func $CDR #v2.16 v3.01 now HDRCDR...
    SECT=`$CDRECORD -msinfo dev=${HDRCDR} 2>/tmp/cdrerr.txt | grep '^[0-9]*.[0-9]'` #v3.01
    if [ "$SECT" = "" ];then
     SAVEABORT="$CDR" #v3.01
     break
    else
     waittrayclosed_func $CDR #v2.16
     $MKISOFS -D -R -C $SECT -M $CDR -quiet -new-dir-mode 0755 -graft-points ${FOLDEROLD}=${pup_ro1} | \
      $CDRECORD -multi -data -tao -eject -v speed=4 gracetime=2 padsize=300k dev=${HDRCDR} -
    fi
   else #dvd
    waittrayclosed_func $CDR #v2.16
    #v2.16 removed '-speed=4' as got 'failed to change write speed' error on one drive...
    growisofs -M $CDR -D -R -quiet -new-dir-mode 0755 -graft-points ${FOLDEROLD}=${pup_ro1} 2> /tmp/dvderr.txt
   fi
  fi

  #normal session save of new/changed files...
  #exclude .sfs files... v3.97 no, allow to save...
  REMSFS=""
  #tack on this exclude as well... (samba network drives mount here)
  [ -d ${pup_rw}/root/mnt ] && REMSFS="$REMSFS -x ${pup_rw}/root/mnt"
  #if a new iso, do not want to save /.badfolders file...
  if [ "$NEWISO" = "yes" ];then
   [ -f ${pup_rw}/.badfolders ] && REMSFS="$REMSFS -x ${pup_rw}/.badfolders"
  fi
  
  #100820 relocate /var/local so it will get saved (see 'init' script at bootup)...
  if [ -d ${pup_rw}/var/local ];then
   rm -rf ${pup_rw}/root/.var_saved #precaution.
   mkdir -p ${pup_rw}/root/.var_saved
   cp -a ${pup_rw}/var/local ${pup_rw}/root/.var_saved/
  fi

  if [ "$MEDIATYPE" = "CD" ];then
   waittrayclosed_func $CDR #v2.16 v3.01 now HDRCDR...
   SECT=`$CDRECORD -msinfo dev=${HDRCDR} 2>/tmp/cdrerr.txt | grep '^[0-9]*.[0-9]'`
   if [ "$SECT" = "" ];then
    SAVEABORT="$CDR" #v3.01
    break #v3.01
   else
    waittrayclosed_func $CDR #v2.16
    TSIZE="`$MKISOFS -print-size -D -R -C $SECT -M $CDR -quiet -new-dir-mode 0755 -graft-points -x ${pup_rw}/tmp $REMSFS -x ${pup_rw}/dev -x ${pup_rw}/proc -x ${pup_rw}/sys -x ${pup_rw}/var -x ${pup_rw}/initrd -x ${pup_rw}/mnt -x ${pup_rw}/root/.XLOADED ${MYDATE}=${pup_rw}`" #120823
    #-J Joliet extension disabled, sometimes causes failure...
    waittrayclosed_func $CDR #v2.16 v3.01 now HDRCDR...
    $MKISOFS -D -R -C $SECT -M $CDR -quiet -new-dir-mode 0755 -graft-points -x ${pup_rw}/tmp $REMSFS -x ${pup_rw}/dev -x ${pup_rw}/proc -x ${pup_rw}/sys -x ${pup_rw}/var -x ${pup_rw}/initrd -x ${pup_rw}/mnt -x ${pup_rw}/root/.XLOADED ${MYDATE}=${pup_rw} | \
      $CDRECORD -multi -data -tao -eject -v speed=4 gracetime=2 padsize=300k tsize=${TSIZE}s dev=${HDRCDR} - #120823
    [ $? -eq 0 ] && break
   fi
   echo "Cannot write to CD" > /tmp/dvderr.txt
  else #dvd
    waittrayclosed_func $CDR #v2.16
    #-J Joliet extension disabled, sometimes causes failure...
    #v2.16 removed '-speed=4' as got 'failed to change write speed' error on one drive...
    growisofs -M $CDR -D -R -quiet -new-dir-mode 0755 -graft-points -x ${pup_rw}/tmp $REMSFS -x ${pup_rw}/dev -x ${pup_rw}/proc -x ${pup_rw}/sys -x ${pup_rw}/var -x ${pup_rw}/initrd -x ${pup_rw}/mnt ${MYDATE}=${pup_rw} 2> /tmp/dvderr.txt
    [ $? -eq 0 ] && break
  fi
  dialog --yes-label "BLANK ${MEDIATYPE}-R" --no-label "UPGRADE ${MEDIATYPE}-R" --yesno "ERROR MESSAGE:
`cat /tmp/dvderr.txt | head -n 1`

It seems to be time to migrate to a new live-${MEDIATYPE}.
You can migrate to a new blank ${MEDIATYPE}-R, or upgrade
to a new Puppy version iso file that has been previously
burnt in multisession mode to a ${MEDIATYPE}-R.

WARNING:
If the PC shuts down without allowing the migration, try
rebooting the current live-$MEDIATYPE and shutdown again.

Have the new media ready, but do not insert it yet.
Just select the appropriate button..." 0 0 >$DEVCONSOLE
  if [ $? -eq 0 ];then #new blank cd/dvd.
   DVDMNTPT="`mount | grep "$CDR" | tr -s " " | cut -f 3 -d " "`" #in case not unmounted.
   if [ "$DVDMNTPT" = "" ];then
    mkdir /tmp/dvdmntpt
    mount -t iso9660 $CDR /tmp/dvdmntpt
    [ ! $? -eq 0 ] && break
    DVDMNTPT="/tmp/dvdmntpt"
   fi
   #get vmlinuz etc off current dvd...
   echo "Copying some files off $CDR..." >$DEVCONSOLE
   mkdir /tmp/livecd
   (
     cd $DVDMNTPT
     for F in vmlinuz initrd.gz grldr *efi* *EFI* *.c32 *.sh *.lst *.xpm *.jpg *.png *.bin *.cfg *.msg *.16 *.HTM* *.ICO *.INF help \
              ${DISTRO_ZDRVSFS} ${DISTRO_FDRVSFS} ${DISTRO_ADRVSFS} ${DISTRO_YDRVSFS}
     do
       [ -e "$F" ] && cp $F /tmp/livecd/
       sync
     done
   )
   sync
   BOOTLOADER=""
   [ -f /tmp/livecd/grldr ] && BOOTLOADER="-b grldr"
   [ -f /tmp/livecd/isolinux.bin ] && BOOTLOADER="-b isolinux.bin -c boot.cat"
   if [ "$BOOTLOADER" = "" ]; then
     SAVEABORT="$CDR"
     ERRORMSG="
No boot loaders found. You need isolinux.bin
or grldr to make bootable ${MEDIATYPE}.
"
     break
   fi

   umount $CDR
   [ ! $? -eq 0 ] && break
   eject $CDR
   dialog --msgbox "Take out the old media and write completion date on it.
NOTE: Do not press tray-close button on $MEDIATYPE drive.
Please insert new media in tray then press ENTER key..." 0 0 >$DEVCONSOLE
   eject -t $CDR
   
   waittrayclosed_func $CDR #v2.16
   if [ "$MEDIATYPE" = "DVD" ];then
    #v2.16 removed '-speed=4' as got 'failed to change write speed' error on one drive...
    growisofs -Z $CDR -R -D -quiet ${BOOTLOADER} -no-emul-boot -boot-load-size 4 -boot-info-table -path-list /tmp/livecd
    [ ! $? -eq 0 ] && break
   else
    $MKISOFS -D -R -quiet ${BOOTLOADER} -no-emul-boot -boot-load-size 4 -boot-info-table -path-list /tmp/livecd | \
      $CDRECORD -multi -tao -data -v speed=4 gracetime=2 padsize=300k dev=$HDRCDR  -
    [ ! $? -eq 0 ] && break
   fi
  fi
  #have new live-cd, and loops back up to save session, but need a 'full save', not just
  #what is in pup_rw. Maybe easiest way is to save two tracks, pup_ro1, which has all prior
  #saved folders read from cd at bootup, then save latest session, pup_rw...
  NEWISO="yes" #loop back up.
 done #end WHILELOOP1

 sync
 [ "`mount | grep "$CDR"`" != "" ] && STILLMNTD="yes" #v3.01
 if [ "$STILLMNTD" = "yes" ];then
  CLOSEMSG="Press ENTER key to complete the shutdown..."
 else
  CLOSEMSG="Remove $MEDIATYPE media if you wish.
Do not press close button on drive.
Press ENTER key to close drive tray
(laptop drive, have to manually close)"
  eject $CDR
 fi
 if [ "$SAVEABORT" = "" ];then #v3.01
  dialog --msgbox "Have saved session to live-$MEDIATYPE
(unless it has not, which is an error).

${CLOSEMSG}" 0 0 >$DEVCONSOLE
 else
  dialog --msgbox "A problem with the ${MEDIATYPE} drive ${SAVEABORT},
unable to save to save to it. Sorry.
${ERRORMSG}
${CLOSEMSG}" 0 0 >$DEVCONSOLE
 fi
 [ "$STILLMNTD" != "yes" ] && eject -t $CDR #close tray.
 sleep 1
 #waittrayclosed_func $CDR #v2.16
} #end multisavefunc

### END ###
